{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "# Pillow\n",
    "\n",
    "* Python の画像処理ライブラリ\n",
    "* PIL(Python Imaging Library : Python2.7まで)のforkプロジェクト\n",
    "    * 3系対応\n",
    "* 参考\n",
    "    * [Python 3.5 対応画像処理ライブラリ Pillow (PIL) の使い方](https://librabuch.jp/blog/2013/05/python_pillow_pil/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 画像を新規で作成する\n",
    "\n",
    "* テキストを画像に出力する\n",
    "    * 新規の画像は `Image.new` でcanvasを作成する\n",
    "    * canvas\n",
    "        * 画像を貼り付ける部分\n",
    "    * `ImageDraw` で画像オブジェクトを処理する\n",
    "    * `Image.save` で保存する\n",
    "    * `draw.text((10, 10), 'hogehoge', font=font, fill='#000')`\n",
    "        * fill : 16進数でカラーコードを指定\n",
    "            * `#000` は黒\n",
    "        * font : フォントの種類とサイズを指定\n",
    "        * `(10,10)` : 画像の座標の始点"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "### テスト(テキストを画像で出力)\n",
    "from PIL import Image, ImageDraw, ImageFont\n",
    "\n",
    "# 画像オブジェクトを作成。サイズと背景色を指定する。背景色はRBGの各々をtupleにして与える。\n",
    "text_canvas = Image.new('RGB', (80, 40), (255, 255, 255))\n",
    "draw = ImageDraw.Draw(text_canvas)\n",
    "\n",
    "# フォントの種類とサイズを指定\n",
    "#font = ImageFont.truetype('/Library/Fonts/ipag.ttf', 15)\n",
    "font = ImageFont.truetype('/root/.fonts/ipag.ttf', 15)\n",
    "\n",
    "# テキストを書き込み。引数は順に、書き込み座標（tuple）、テキスト、テキストのフォント、テキストのカラー\n",
    "draw.text((10, 10), 'hogehoge', font=font, fill='#000')\n",
    "\n",
    "# 保存\n",
    "text_canvas.save('img/text_img.jpg', 'JPEG', quality=100, optimize=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "テスト画像の表示\n",
    "\n",
    "既存\n",
    "\n",
    "<img src=\"img/text_img.jpg\" alt=\"テスト画像の表示\" title=\"テスト画像の表示\" align=\"left\" />  \n",
    "\n",
    "<br clear=\"left\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## 既存の画像を開く\n",
    "\n",
    "* 既存の画像を開いてリサイズして別名のファイルに保存\n",
    "    * 既存の画像は `Image.open` で開く"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [],
   "source": [
    "from PIL import Image\n",
    "\n",
    "# 既存ファイルを readモードで読み込み\n",
    "img = Image.open('img/text_img.jpg', 'r')\n",
    "\n",
    "# リサイズ。サイズは幅と高さをtupleで指定\n",
    "resize_img = img.resize((160, 80))\n",
    "\n",
    "# リサイズ後の画像を保存\n",
    "resize_img.save('img/text_img_resize.jpg', 'JPEG', quality=100, optimize=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "リサイズ後\n",
    "\n",
    "<img src=\"img/text_img_resize.jpg\" alt=\"テスト画像の表示_resize\" title=\"テスト画像の表示_resize\" align=\"left\" />  \n",
    "\n",
    "<br clear=\"left\">\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "## NumPyとPILの変換\n",
    "\n",
    "* Python Imaging LibraryのImageクラスのデータをNumPyのarrayとして扱う\n",
    "    * Numpyの関数を使って直接pixel値を書き換える\n",
    "* 参考\n",
    "    * [NumPyのarrayとPILの変換](http://d.hatena.ne.jp/white_wheels/20100322/p1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "### PILのImageオブジェクトを配列に変換\n",
    "\n",
    "* asarray関数\n",
    "    * NumPyの関数\n",
    "    * PILのImageオブジェクトを配列に変換する"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(40, 80, 3)\n",
      "-----------------------\n",
      "[[[255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  ..., \n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]]\n",
      "\n",
      " [[255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  ..., \n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]]\n",
      "\n",
      " [[255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  ..., \n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]]\n",
      "\n",
      " ..., \n",
      " [[255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  ..., \n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]]\n",
      "\n",
      " [[255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  ..., \n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]]\n",
      "\n",
      " [[255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  ..., \n",
      "  [255 255 255]\n",
      "  [255 255 255]\n",
      "  [255 255 255]]]\n",
      "-----------------------\n",
      "[255 255 255]\n",
      "配列の要素を変更するにはwriteableフラグをTrueにする必要があります。\n",
      "[100 100 100]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from PIL import Image\n",
    "\n",
    "img = Image.open('img/text_img.jpg', 'r')\n",
    "imgArray = np.asarray(img)\n",
    "print(imgArray.shape)\n",
    "print('-----------------------')\n",
    "print(imgArray)\n",
    "print('-----------------------')\n",
    "print(imgArray[0][1])\n",
    "\n",
    "try:\n",
    "    imgArray[0][1][0] = 100\n",
    "except ValueError:\n",
    "    print('配列の要素を変更するにはwriteableフラグをTrueにする必要があります。')\n",
    "\n",
    "imgArray.flags.writeable = True\n",
    "imgArray[0][1] = 100\n",
    "print(imgArray[0][1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "### NumPyのarrayからPILへの変換\n",
    "\n",
    "* fromarrayメソッド\n",
    "    * PILのメソッド\n",
    "    * 配列の各値を1byte整数型(0～255)として画像のpixel値に変換する"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<PIL.Image.Image image mode=RGB size=80x40 at 0x7F56393D14A8>\n"
     ]
    }
   ],
   "source": [
    "pilImg = Image.fromarray(np.uint8(imgArray))\n",
    "print(pilImg)\n",
    "\n",
    "# 画像を保存\n",
    "pilImg.save('img/text_img_numpy.jpg', 'JPEG', quality=100, optimize=True)\n",
    "\n",
    "# ローカルで実行している場合はshowコマンドで画像ファイルを作成せずに表示できる\n",
    "#pilImg.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "リサイズ後\n",
    "\n",
    "<img src=\"img/text_img_numpy.jpg\" alt=\"numpy画像の保存\" title=\"numpy画像の保存\" align=\"left\" />  \n",
    "\n",
    "<br clear=\"left\">\n",
    "\n",
    "※ 画像の左上についてるゴマみたいな点が配列の値を直接書き換えることによってできた"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
